from test.MyClient import *
import time
from random import random


class StrategyClient(MyClient):
    def __init__(self):
        super().__init__()
        with open("order.log", "a", encoding="utf-8") as fo:
            fo.write("[Start Here]\n")
        self.limit_strategy_times = 0

    def send_close_first_order(self, om, direction, price, volume, order_type=0):  # [order_type] 0:常规 1:做市 2:盈利
        if direction == PHX_FTDC_D_Sell:
            long_position_closeable = om.get_long_position_closeable()
            if long_position_closeable >= volume:
                self.send_input_order(om.place_limit_order(self.next_order_ref(order_type), direction, PHX_FTDC_OF_Close, price, volume))
            else:
                self.send_input_order(om.place_limit_order(self.next_order_ref(order_type), direction, PHX_FTDC_OF_Open, price, volume))
        else:
            short_position_closeable = om.get_short_position_closeable()
            if short_position_closeable >= volume:
                self.send_input_order(om.place_limit_order(self.next_order_ref(order_type), direction, PHX_FTDC_OF_Close, price, volume))
            else:
                self.send_input_order(om.place_limit_order(self.next_order_ref(order_type), direction, PHX_FTDC_OF_Open, price, volume))

    def strategy_1(self):
        for ins_id, ins_index in self.ins2index.items():
            md = self.getMarketData(ins_index)
            if not md:
                continue
            ins = self.getInstrument(ins_index)
            om = self.getOrderManager(ins_id)
            order = None
            price = self.getPrice(ins_index)
            value = self.getValue(ins_index)
            if round(price, 3) == 0.001:  # 期权合约跌停，豁免做市义务
                if value > 0.2 and om.get_long_open_trading_volume() < 50:
                    self.send_close_first_order(om, PHX_FTDC_D_Buy, 0.1, 50)
                continue
            if ins.StrikePrice <= self.ubiq_price*1.15 and ins.StrikePrice >= self.ubiq_price*0.85:
                if not om.obligationFulfilled(double=True)[0]:
                # if True:
                    if ins.ProductID != "UBIQ":
                        print("发现未完成做市义务期权: %s" % ins_id)
                        # if price < ins.StrikePrice * 0.6 or price > ins.StrikePrice * 1.5:
                            # print("义务合约 %s 期权价格 %.3f 偏离行权价过远" % (ins_id, price))
                            # price = ins.StrikePrice
                            # continue
                        if om.get_live_order_num() > 16:
                            print("啊啊啊啊堵死了!!!")
                            self.cancel_live_orders(om)
                        time.sleep(0.05)
                        long_position = om.longSnapshot.Position
                        long_position_closeable = om.get_long_position_closeable()
                        short_position = om.shortSnapshot.Position
                        short_position_closeable = om.get_short_position_closeable()
                        # long_close_price = round(ins.StrikePrice * 0.58, 3)  # if lp < 5000 else round(ins.StrikePrice * 0.28, 3)
                        # short_close_price = round(self.ubiq_price * 0.1, 3)  # 每手义务期权的收益上限为self.ubiq_price * 0.1
                        # 做市
                        base_volume_0 = 15
                        base_volume_1 = 12
                        # obligation_buying_volume = om.get_buying_volume_by_type(1)
                        # obligation_selling_volume = om.get_selling_volume_by_type(1)
                        obligation_selling_num = om.get_selling_num_by_type(1)
                        obligation_buying_num = om.get_buying_num_by_type(1)
                        obligation_max_order_num = 3
                        if value > price:
                            if obligation_selling_num < obligation_max_order_num and obligation_buying_num < obligation_max_order_num:
                            # if obligation_buying_volume < 2*base_volume_0 and obligation_selling_volume < 2*base_volume_1:
                                self.send_close_first_order(om, PHX_FTDC_D_Buy, round(price, 3), base_volume_0, order_type=1)
                                self.send_close_first_order(om, PHX_FTDC_D_Sell, round(getMaxSellPrice(price), 3), base_volume_1, order_type=1)
                            # elif obligation_buying_volume < 2*base_volume_0:
                            elif obligation_buying_num < obligation_max_order_num:
                                obligation_buying_price = max(om.get_effective_selling_price()-0.004, 0.001)
                                self.send_close_first_order(om, PHX_FTDC_D_Buy, round(obligation_buying_price, 3), base_volume_0, order_type=1)
                            elif obligation_selling_num < obligation_max_order_num:
                                obligation_selling_price = om.get_effective_buying_price()+0.004
                                self.send_close_first_order(om, PHX_FTDC_D_Sell, round(obligation_selling_price, 3), base_volume_1, order_type=1)
                            else:
                                self.cancel_live_orders(om)
                        else:
                            # if obligation_buying_volume < 2*base_volume_1 and obligation_selling_volume < 2*base_volume_0:
                            if obligation_selling_num < obligation_max_order_num and obligation_buying_num < obligation_max_order_num:
                                self.send_close_first_order(om, PHX_FTDC_D_Sell, round(price, 3), base_volume_0, order_type=1)
                                self.send_close_first_order(om, PHX_FTDC_D_Buy, round(getMinBuyPrice(price), 3), base_volume_1, order_type=1)
                            # elif obligation_buying_volume < 2*base_volume_1:
                            elif obligation_buying_num < obligation_max_order_num:
                                obligation_buying_price = max(om.get_effective_selling_price()-0.004, 0.001)
                                self.send_close_first_order(om, PHX_FTDC_D_Buy, round(obligation_buying_price, 3), base_volume_1, order_type=1)
                            elif obligation_selling_num < obligation_max_order_num:
                                obligation_selling_price = om.get_effective_buying_price()+0.004
                                self.send_close_first_order(om, PHX_FTDC_D_Sell, round(obligation_selling_price, 3), base_volume_0, order_type=1)
                            else:
                                self.cancel_live_orders(om)
                        # 盈利
                        # profit_buying_volume = om.get_buying_volume_by_type(2)
                        # profit_selling_volume = om.get_selling_volume_by_type(2)
                        profit_buying_num = om.get_buying_num_by_type(2)
                        profit_selling_num = om.get_selling_num_by_type(2)
                        profit_max_order_num = 3
                        # if profit_buying_volume < 500 and om.get_buying_order_num() < 10:
                        if profit_buying_num < profit_max_order_num:
                            self.send_close_first_order(om, PHX_FTDC_D_Buy, max(min(value-1, price-1), 0.001), 50, order_type=2)
                        # if profit_selling_volume < 500 and om.get_selling_order_num() < 10:
                        if profit_selling_num < profit_max_order_num:
                            self.send_close_first_order(om, PHX_FTDC_D_Sell, min(max(value, 0), price)+10*random(), 20, order_type=2)

    def run_once(self):
        if self.limit_strategy_times < 1:
            self.limit_strategy_times += 1
            # self.cancel_all_live_orders()
            for ins_id, ins_index in self.ins2index.items():
                md = self.getMarketData(ins_index)
                if md:
                    continue
                ins = self.getInstrument(ins_index)
                if ins.StrikePrice <= self.ubiq_price*1.15 and ins.StrikePrice >= self.ubiq_price*0.85:
                    om = self.getOrderManager(ins_id)
                    self.send_input_order(om.place_market_order(self.next_order_ref(), PHX_FTDC_D_Sell, PHX_FTDC_OF_Open, 1))

    def run_strategy(self):
        self.run_once()
        self.strategy_1()


if __name__ == "__main__":
    client = StrategyClient()
    client.run()
